package com.uoko.fileupload.util;

import com.uoko.fileupload.modle.UploadInfo;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 分片上传
 * 大文件上传
 * 1.先使用 saveFile 将文件分块保存到临时文件夹里，便于之后的合并文件
 * 2.上传分片  uploaded
 * 3.上传分片  uploaded  验证所有分块是否上传成功，成功的话进行合并
 * </p>
 *
 * @author shaohua
 * Email shaohua@uoko.com
 * created by 2018/6/8
 */
public class SliceUpload {

    private final static List<UploadInfo> INFO_ARRAY_LIST = new ArrayList<>();

    /**
     * @param md5      MD5
     * @param guid     随机生成的文件名
     * @param chunk    文件分块序号
     * @param chunks   文件分块数
     * @param fileName 文件名
     * @param ext      文件后缀名
     */
    public static void uploaded(@NotNull final String md5,
                                @NotNull final String guid,
                                @NotNull final String chunk,
                                @NotNull final String chunks,
                                @NotNull final String uploadFolderPath,
                                @NotNull final String fileName,
                                @NotNull final String ext)
            throws Exception {
        synchronized (INFO_ARRAY_LIST) {
            INFO_ARRAY_LIST.add(new UploadInfo(md5, chunks, chunk, uploadFolderPath, fileName, ext));
        }
        boolean allUploaded = isAllUploaded(md5, chunks);
        int chunksNumber = Integer.parseInt(chunks);
        if (allUploaded) {
            isAllUploaded(md5, chunks);
            // TODO: 2018/6/8 记录分片记录
        }
    }

    /**
     * 判断是否全部上传
     *
     * @param md5
     * @param chunks
     * @return
     */
    public static boolean isAllUploaded(@NotNull final String md5,
                                        @NotNull final String chunks) {
        int size = INFO_ARRAY_LIST.stream()
                .filter(item -> item.getMd5().equals(md5))
                .distinct()
                .collect(Collectors.toList())
                .size();
        boolean bool = (size == Integer.parseInt(chunks));
        if (bool) {
            synchronized (INFO_ARRAY_LIST) {
                INFO_ARRAY_LIST.removeIf(item -> Objects.equals(item.getMd5(), md5));
            }
        }
        return bool;

    }

}
